﻿using System.Text;
using Mono.Cecil.Cil;

namespace Cil.Ast;

public sealed class SwitchExpression : SingleInstructionExpression
{
	public const int IndexPos = 0;
	public const int DefaultPos = 1;
	public const int MaxNodes = 2;

	public SwitchExpression(Context context, Instruction target, Expression index, Expression @default, params CaseExpression[] cases)
		: base(context, target)
	{
		var merged = new MergedList<Expression>();
		merged.AddList(new FixedList<Expression>(MaxNodes));
		merged.AddList(new FixedListByDelegate<Expression>(i => Cases[i], (i, expression) => Cases[i] = (CaseExpression)expression, () => Cases.Length));
		Nodes = merged;
		Cases = cases;
		Index = index;
		Default = @default;
	}

	public Expression Index  { get => Nodes[IndexPos];
		set { Nodes[IndexPos] = value; value.ParentNode = this; } }

	public Expression Default { get => Nodes[DefaultPos];
		set { Nodes[DefaultPos] = value; value.ParentNode = this; } }

	public CaseExpression[] Cases { get; private set; }

	public override string ToString()
	{
		var sb = new StringBuilder();
		sb.AppendFormat("switch({0}) {{", Index);
		sb.AppendLine();
		foreach (var caseExpression in Cases)
		{
			foreach (var val in caseExpression.Values)
			{
				sb.AppendFormat("    case {0}:", val);
				sb.AppendLine();
			}
			sb.AppendFormat("        {0}", caseExpression.Body);
			sb.AppendLine();
			sb.AppendLine("         break;");
		}

		if (!Default.IsEmpty)
		{
			sb.AppendFormat("    default:");
			sb.AppendLine();
			sb.AppendFormat("        {0}", Default);
			sb.AppendLine();
		}
		sb.AppendLine("}");
		return sb.ToString();
	}
}

public static partial class IlAst
{
	public static Expression SwitchTable(Instruction current,Expression index,Instruction[] branches)
	{
		return null;
	}
}